# -*- encoding: utf-8 -*-
"""
File Name: load_problems_from_zabbix
Description:
Author : 'lirui'
date: 2/6/2024
Contact: marjey_lee@163.com
Change Activity:
2/6/2024:
"""
import time

import ll
from modules.blk.cmdb.cmdb_service import CMDBService
from modules.zabbix_utils.utils.zabbix_client import ZabbixClient
from projects.monitoring.common.do.alarm import Alarm
from projects.monitoring.zabbix_monitoring.config.config import (
    ZABBIX_USERNAME,
    ZABBIX_PASSWORD,
)

ll.get_logger().warning("Please use the new version of the code in the same directory.")


class LoadProblemsFromZabbix:
    def __init__(self):
        self.zabbix_login_info = self._load_cmdb_container_info()

    @staticmethod
    def _load_cmdb_container_info():
        data = CMDBService().select("zabbix_docker_info")
        return data["data"]["info"]

    def load_problems(self):
        """
        load problems from zabbix server
        Returns:

        """
        ll.get_logger().info("Start to load problems from zabbix server.")
        problems_lst = []
        for info in self.zabbix_login_info:
            problems_lst = self._load_one_server_problem(info, problems_lst)
        ll.get_logger().info(
            f"Load problems from zabbix server finished, total problems count {len(problems_lst)}."
        )
        return self._format_alarm(problems_lst)

    @staticmethod
    def _get_severity(severity_index):
        """ """
        if str(severity_index) in ["0", "1", "2"]:
            return "remind"
        if str(severity_index) in ["3"]:
            return "warning"
        if str(severity_index) in ["4", "5"]:
            return "fatal"
        ll.get_logger().warning(f"Unknown severity_index: {severity_index}")

    @staticmethod
    def _format_alarm(problems_lst):
        """

        Args:
            problems_lst:

        Returns:

        """
        alarm_lst = []
        for p in problems_lst:
            alarm = Alarm(
                timestamp=int(p["clock"]),
                ip=p["host_name"],
                hostname=p["host_name"],
                severity=LoadProblemsFromZabbix._get_severity(p["severity"]),
                alarm_type="alarm",  # 'alarm,recovery'
                alarm_info=p["name"],
                note=None,
                recovery=False,
                recovery_time=None,
                manager_ip=p["zabbix_ip"],
                manager_port=p["zabbix_port"],
                alarm_source="zabbix",
            )
            alarm_lst.append(alarm.to_json())
        return alarm_lst

    def _load_one_server_problem(self, info, problems_lst):
        """
        load one server problems
        Args:
            info:
            problems_lst:

        Returns:

        """
        try:
            client = ZabbixClient(
                ip=info["docker_server_ip"],
                port=info["docker_server_port"],
                username=ZABBIX_USERNAME,
                password=ZABBIX_PASSWORD,
            )
            problems = self._load_problem_hosts(client)
            problems_lst.extend(problems)
            return problems_lst
        except Exception as e:
            ll.get_logger().error(
                f"Load problem from {info['ip']}  port: {info['port']}, error： {e}."
            )
            p = {
                "clock": str(int(time.time())),
                "name": f"Can not connect to zabbix server {info.get('docker_server_ip')}, port:{info.get('docker_server_port')}",
                "acknowledged": "0",
                "severity": "3",
                "zabbix_ip": info["docker_server_ip"],
                "zabbix_port": info["docker_server_port"],
                "host_name": info["docker_server_ip"],
            }
            problems_lst.append(p)
            return problems_lst

    @staticmethod
    def _load_problem_hosts(client: ZabbixClient):
        t = client.get_template("problems", "hosts_with_problems")
        hosts = client.fetch(t)
        if len(hosts) == 0:
            return []
        problem_res = []
        for host in hosts:
            t = client.get_template("problems", "get")
            t["params"]["hostids"] = host["hostid"]
            problems = client.fetch(t)
            problems = LoadProblemsFromZabbix._filter_recovered_problems(problems)
            for problem in problems:
                problem["zabbix_ip"] = client.ip
                problem["zabbix_port"] = client.port
                problem["hostid"] = host["hostid"]
                problem["host_name"] = host["name"]
            problem_res.extend(problems)
        return problem_res

    @staticmethod
    def _filter_recovered_problems(problems):
        """

        Returns:

        """
        ps = []
        for p in problems:
            if p["r_eventid"] == "0":
                ps.append(p)
        return ps


def _main():
    problems = LoadProblemsFromZabbix().load_problems()
    print(problems)


if __name__ == "__main__":
    _main()
